#!/usr/bin/perl
# -*- coding: utf-8 -*-
# mubot
# Copyright (c) 2008 Jun Morimoto <morimoto@mrmt.net>
# This program is covered by the GNU General Public License 2
require 5.8.0;
use lib qw(lib /usr/share/twitmark/lib);
use POE;
use POE::Component::IRC::State;
use POE::Component::IRC::Plugin::AutoJoin;
use POE::Component::IRC::Plugin::Connector;
use Config::YAML;
use Twitmark;
use Encode;
use utf8;
use strict;
use warnings;

# TODO: channel name has not i18n'ed

my $cf = Config::YAML->new(
	config => defined($ARGV[0]) && -r $ARGV[0] ? $ARGV[0] : '/etc/twitmark.conf',
	version => '0.1',
	daemonize => 0,
	irc_charset => 'iso-2022-jp-1',
	irc_nick => 'mubot',
	irc_desc => 'mubot',
	irc_port => 6667,
	reconnect_delay => 10,
	pid_dir => '/var/run',
	pid_file => 'mubot.pid',
	irc_add_message_regexp => '^(\S+)\s+(https?://\S+)\s+(.*)$',
	irc_delete_message_regexp => '^いまのなし$',
	);

# daemonize
if($cf->{daemonize}){
	use Proc::Daemon;
	Proc::Daemon::Init;
	if(-d $cf->{pid_dir} && -r _ && -w _ && -x _){
		my $fh = new IO::File('>' . $cf->{pid_dir} . '/' . $cf->{pid_file});
		if(defined $fh){
			print $fh $$, "\n";
			$fh->close();
		}
	}
}

# create irc component
my $irc = POE::Component::IRC::State->spawn(
	Alias => 'mubot',
	Nick => $cf->{irc_nick},
	Username => $cf->{irc_username},
	Ircname => $cf->{irc_desc},
	Server => $cf->{irc_server},
	Port => $cf->{irc_port},
	Password => $cf->{irc_password});

my %channels;
if(ref($cf->{irc_channel}) eq 'ARRAY'){
	map { $channels{$_} = '' } @{$cf->{irc_channel}}
}else{
	$channels{$cf->{irc_channel}} = '';
}

# create POE session
POE::Session->create(
	heap => {
		Config => $cf,
		Irc => $irc,
		AutoJoin => new POE::Component::IRC::Plugin::AutoJoin (Channels => \%channels),
		Connector => new POE::Component::IRC::Plugin::Connector,
		Twitmark => new Twitmark (Config => $cf),
	},
	inline_states => {
		_start => \&irc_start,
		connect => \&irc_connect,
		irc_msg => \&irc_message,
		irc_invite => \&irc_invite,
		irc_public => \&irc_public,
	});

$poe_kernel->run();
exit 0;

################################################################
sub irc_start{
	my ($kernel, $heap) = @_[KERNEL, HEAP];
	$heap->{Irc}->plugin_add('AutoJoin', $heap->{AutoJoin});
	$heap->{Irc}->plugin_add('Connector', $heap->{Connector});
	$heap->{Irc}->yield(register => 'all');
	$heap->{Irc}->yield(connect => {});
	$kernel->delay(lag_o_meter => $heap->{Config}->{reconnect_delay});
}

################################################################
sub irc_public{
	my ($heap, $who, $channel, $msg) = @_[HEAP, ARG0 .. ARG2];
	$who =~ s/!.*//;

	$msg = decode($heap->{Config}->{irc_charset}, $msg);
	my $cname = decode($heap->{Config}->{irc_charset}, $channel->[0]);

	if($msg =~ m/$heap->{Config}->{irc_delete_message_regexp}/){
		my $m = $heap->{Twitmark}->delete_mark(
			nick => $who,
			);
		if($m =~ s/OK://){
			$m = $who . ': ' . $m . '番を消したよ';
		}elsif($m =~ m/NOTFOUND:/){
			$m = $who . ': あなたの投稿はないようですよ';
		}elsif($m =~ s/ERROR://){
			$m = $who . ': なんか消せませんでした: ' . $m;
		}

		$m = encode($heap->{Config}->{irc_charset}, $m);
		$heap->{Irc}->yield(privmsg => $channel => $m);
		return;
	}

	if($msg =~ m/$heap->{Config}->{irc_add_message_regexp}/){
		my $m = $heap->{Twitmark}->add_mark(
			channel => $cname,
			nick => $who,
			prefix => $1,
			url => $2,
			message => $3);

		if($m =~ s/OK://){
			$m = $who . ': ' . $m . '番で登録したよ';
		}elsif($m =~ m/DUPLICATED:/){
			# TODO ガイシュツ状況をもっと詳しく
			$m = $who . ': ' . 'それガイシュツ';
		}elsif($m =~ s/ERROR://){
			$m = $who . ': なんかエラーです: ' . $m;
		}

		$m = encode($heap->{Config}->{irc_charset}, $m);
		$heap->{Irc}->yield(privmsg => $channel => $m);
		return;
	}
}

################################################################
sub irc_message{
	my ($heap, $who, $channel, $msg) = @_[HEAP, ARG0 .. ARG2];
	my $cf = $heap->{Config};

	$who =~ s/!.*//;

	warn "irc_message $msg";

	my $cname;
	if ($who eq $cf->{irc_nick}) {
		# XXX: $channel may contain two or more nicks.
		$cname = $channel->[0];
	}else{
		$cname = $who;
	}

	$msg = decode($cf->{irc_charset}, $msg);
	$cname = decode($cf->{irc_charset}, $cname);

	# TODO irc_public と合流
	if($msg =~ m/$cf->{irc_add_message_regexp}/){
		my $m = $heap->{Twitmark}->add_mark(
			channel => $cname,
			nick => $who,
			prefix => $1,
			url => $2,
			message => $3);	# TODO
		$heap->{Irc}->yield(privmsg => $channel => encode($cf->{irc_charset}, $m));
	}
}

################################################################
sub irc_connect{
	my $kernel = $_[KERNEL];
	$kernel->post(mubot => connect => {});
}

################################################################
sub irc_invite{
	my ($heap, $channel) = @_[HEAP, ARG1];
	$heap->{Irc}->yield(join => $channel);
}

__END__
